package com.wrupple.muba.catalogs.client.widgets.editors.composite.delegates;

import java.util.Collection;

import com.google.gwt.event.shared.EventBus;
import com.wrupple.muba.catalogs.client.activity.process.CatalogEditingProcess;
import com.wrupple.muba.catalogs.client.activity.process.task.CatalogInteractionState.Mode;
import com.wrupple.muba.catalogs.client.cms.service.CatalogManagementSystem;
import com.wrupple.muba.catalogs.client.cms.service.CatalogManager;
import com.wrupple.muba.catalogs.client.module.services.logic.CatalogDescriptionService;
import com.wrupple.muba.catalogs.domain.CatalogEntry;
import com.wrupple.muba.catalogs.domain.JsCatalogKey;
import com.wrupple.muba.common.client.JSOHelper;
import com.wrupple.muba.common.client.application.DataCallback;
import com.wrupple.muba.common.domain.FilterData;
import com.wrupple.muba.common.shared.State.ProcessManager;
import com.wrupple.muba.common.shared.State.StorageManager;
import com.wrupple.muba.common.shared.StateTransition;
import com.wrupple.vegetate.domain.CatalogDescriptor;
import com.wrupple.vegetate.domain.FieldDescriptor;

/**
 * Add: Create a new Entry holding a referenco to local entry
 * Remove: Permanently delete entry
 */
public class ManyToOneRelationshipDelegate  implements com.wrupple.muba.catalogs.client.widgets.editors.ForeignValueRelationEditor.RelationshipDelegate{

	CatalogDescriptionService catalogDescriptor;
	EventBus bus;
	ProcessManager pm;
	StorageManager sm;
	CatalogManagementSystem cms;
	FieldDescriptor descriptor;
	String localCatalogId;
	String localEntryId;
	
	public ManyToOneRelationshipDelegate(
			CatalogDescriptionService catalogDescriptor, EventBus bus,
			ProcessManager pm, StorageManager sm, CatalogManagementSystem cms,
			FieldDescriptor descriptor, String localCatalogId,
			String localEntryId) {
		super();
		this.catalogDescriptor = catalogDescriptor;
		this.bus = bus;
		this.pm = pm;
		this.sm = sm;
		this.cms = cms;
		this.descriptor = descriptor;
		this.localCatalogId = localCatalogId;
		this.localEntryId = localEntryId;
	}

	@Override
	public void onRelationshipAdditionRequested(
			FilterData currentValue, StateTransition<FilterData> callback) {
		String foreignCatalog = descriptor.getForeignCatalog();
		catalogDescriptor.loadCatalogDescriptor(foreignCatalog, new CatalogCallback(currentValue,callback));
	}

	@Override
	public void onRelationshipRemovalRequested(FilterData currentValues,
			String valueToRemove, StateTransition<FilterData> callback) {
		String foreignCatalog = descriptor.getForeignCatalog();
		sm.delete(foreignCatalog, valueToRemove, new DeleteCallback(callback,currentValues));
	}
	
	class DeleteCallback extends DataCallback<CatalogEntry>{
		StateTransition<FilterData> callback;
		private FilterData currentValue;
		
		public DeleteCallback(StateTransition<FilterData> callback,FilterData currentValue) {
			super();
			this.currentValue = currentValue;
			this.callback = callback;
		}

		@Override
		public void execute() {
			callback.setResultAndFinish(currentValue);
		}
		
	}
	
	class CatalogCallback extends DataCallback<CatalogDescriptor>{
		 StateTransition<FilterData> callback;
		private FilterData currentValue;
		 
		public CatalogCallback(FilterData currentValue, StateTransition<FilterData> callback) {
			super();
			this.callback = callback;
			this.currentValue = currentValue;
		}


		@Override
		public void execute() {
			Collection<FieldDescriptor> fields = result.getFields();
			String foreignCatalog = result.getId();
			String title = descriptor.getName();
			String fieldPointsToLocalEntry;
			JsCatalogKey entry = CatalogEntry.createCatalogEntry(foreignCatalog).cast();
			for(FieldDescriptor field : fields){
				if(localCatalogId.equals(field.getForeignCatalog())){
					fieldPointsToLocalEntry = field.getId();
					JSOHelper.setAttribute(entry, fieldPointsToLocalEntry, localEntryId);
				}
			}
			CatalogManager<JsCatalogKey> manager = cms.getContentManager(foreignCatalog);
			CatalogEditingProcess<JsCatalogKey> process = manager.getEditingProcess(Mode.CREATE, bus);
			
			pm.processSwitch(process, title, entry, new CreationCallback(callback,currentValue), bus);
		}
		
	}
	
	
	class CreationCallback extends DataCallback<JsCatalogKey>{
		StateTransition<FilterData> callback;
		private FilterData currentValue;
		
		public CreationCallback(StateTransition<FilterData> callback,FilterData currentValue) {
			super();
			this.currentValue = currentValue;
			this.callback = callback;
		}

		@Override
		public void execute() {
			callback.setResultAndFinish(currentValue);
		}
		
	}

}